/*
	Handles the different ammunition types for 
	each weapon and beyond.

	By Julian Williams
	Date: Feb 6, 2010
*/


#include <SFML/Graphics.hpp>


//#include <SDL_config_lib.h>

#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <cmath>


#include "ammo.h"
#include "app.h"
#include "levels.h"
#include "player.h"
#include "helper.h"
#include "objects.h"
#include "iniparser.h"
#include "Camera.h"



using namespace std;


//Define super array for All Ammo
//vector< string > Ammo_Factory::List;
vector< Ammo_Factory > Ammo_Types;



//actual projectiles
list< Projectile > bullet_list; //new
//Projectile bullets[21]; //old

//Newest
Ammo_Factory Bullets;



/* Load Ammo Files 
bool Ammo_Factory::Load(string cfg_location)
{
		//Grab the Weapon names
	if(!Get_AmmoList()) 
	{ 
		cout << "Get_AmmoList() has FAILED! \nYou should look into this, Julian..." << endl; 
		return false; 
	}

	Ammo_Types.reserve ( List.size() );

	//max_weapons = 2;

	cout << "# Different Ammo: " << List.size() << endl;


	string ammoName;

	//Loop through and load each Ammo type
	for(int i = 0; i < List.size(); i++)
	{
		cout << "Ammo Name: " << List[i] << "\n\n";


			//add the weapon to the vector
			Ammo_Factory a;

			if(!a.Get_Config(List[i])) 
			{
				cout << "Ammo Type: " << List[i] << " failed to load.\n";
				return false;
			}
			Ammo_Types.push_back(a);
	}//end for loop

	return true;
}//Eof




/* Draw Bullets to the screen 
void Ammo_Factory::Draw()
{

	list<Projectile>::iterator i;

	for( i = bullet_list.begin(); i != bullet_list.end(); i++)
	{
		if(i->Get_State() != AS_DEAD)
		{

			App::getInstance().Get_RenderWindow()->Draw(*i);
		}
	}
}//EoF




/* Grab the Weapons List 
bool Ammo_Factory::Get_AmmoList()
{

	//Get texture directory
	string List_loc("resources/ammo/ammo_list.cfg");
	string list_name;


	//Open up Ammo List file
	ifstream List_file(List_loc.c_str());
    
	//if file isn't open, return false
	if(!List_file.is_open()) { return false; }

	do 
	{
		//Read in every line
		getline( List_file, list_name);

		if(list_name == "") { break; }

		List.push_back(list_name);

	} while( !List_file.eof() );

	//save the number of textures 
	//max_weapons = List.size(); (redundent

	//Close file
	List_file.close();

	return true;
}//EoF
*/



/* Set Projectile Properties */
void Ammo_Factory::Set_Projectile(Projectile& p)
{
	//lol, only one property to change for now
	p.Set_Damage(damage);
	p.Set_Speed(min_speed, max_speed);

}//EoF



/* Get the Ammo Configuration file and load properties 
bool Ammo_Factory::Get_Config(string folder_name)
{
	//grab and create the nessisary directories
	string folder_location = string("resources/ammo/") + folder_name + string("/");
	string image_location = folder_location + string("image.png");
	string cfg_location = folder_location + string("properties.cfg");
	//string snd_location = folder_location + string("fire.wav");

	cout << "Loading Ammo folder: " << folder_location << endl;
	cout << "Ammo Config from: " << cfg_location << endl;
	//cout << "Gun sound from: " << snd_location << endl;



//Now Grab the firing sound for the gun
	//if(!Load_Sounds(s_fire, SND_fire, snd_location)) { return false; }




//Grab Weapon Config
		dictionary	*	ini = iniparser_load(cfg_location.c_str());

		if (ini==NULL)
		{
			cout << "Couldn't load configuration file, sorry :P \n";
			return false;
		}

		

//Get all of the properties
	
		name = iniparser_getstring(ini, "ammo:name", "Default");
		damage = iniparser_getdouble(ini, "ammo:damage", 10);
		max_speed = iniparser_getdouble(ini, "ammo:max_speed", 1000);
		min_speed = iniparser_getdouble(ini, "ammo:min_speed", 100);

		//use_image = iniparser_getboolean(ini, "ammo:use_image", 0);

		cout << "Name: " << name << endl;
		cout << "Damage: " << damage << endl;
		cout << "Max Speed: " << max_speed << endl;
		cout << "Min Speed: " << min_speed << endl;
		cout << "Use Image: " << use_image << endl;
	

	
		//Animation related information
		
			tile_size.x = iniparser_getint(ini, "animation:tile_width", 100);
			tile_size.y = iniparser_getint(ini, "animation:tile_height", 50);

			cout << "Tile Size.X: " << tile_size.x << endl;
			cout << "Tile Size.Y: " << tile_size.y << endl;

			//pivit_point.x = CFG_ReadInt("pivit_point_x", 18);
			//pivit_point.y = CFG_ReadInt("pivit_point_y", 20);

			//cout << "Pivit Point.X: " << pivit_point.x << endl;
			//cout << "Pivit Point.Y: " << pivit_point.y << endl;
/*
			shootFrame.start = CFG_ReadInt("shoot_start", 3);
			shootFrame.end = CFG_ReadInt("shoot_end", 4);
			shootFrame.speed = CFG_ReadFloat("shoot_frame_speed", 0);

			fire_delay = CFG_ReadFloat("fire_delay", 1);

			cout << "ShootFrame Start: " << shootFrame.start << ", ShootFrame End: " << shootFrame.end << ", shootFrame Speed: " << shootFrame.speed << "\n\n";
			


		
			sf::Vector2f _center;
			_center.x = tile_size.x/2;
			_center.y = tile_size.y/2;
			SetOrigin(_center);

	
			cout << "Ammo Image from: " << image_location << "\n\n";
			if(!Load_Image(image_location)) { return false; }
		cout << "**********************************************************\n\n";
	return true;
}//EoF
*/


/*Set bullet Function */
void Ammo_Factory::Update_Logic()
{
	/*
	 for(int i = 0 ; i < 20; ++i) 
	 {     
            if(bullets[i].Get_State() == AS_ALIVE) 
			{
					//move Bullets according to it's velocity
				bullets[i].Move(bullets[i].velocity * Objects::Get_RenderWindow()->GetFrameTime());     

                     //teh actual bullet
                     // textprintf_ex(activepage, font, bullet[i].x, bullet[i].y, makecol(50, 255, 255),-1, "lul");                   
                      if((bullets[i].GetPosition().x < 0) || (bullets[i].GetPosition().x > screen_size.x) ||
                      (bullets[i].GetPosition().y < 0) || (bullets[i].GetPosition().y > screen_size.y))
					  {
                                bullets[i].Set_State(AS_DEAD);
                      }   
					//  cout << "Spawned bullet[" << i << "] at: " << bullets[i].GetPosition().x << ", " << bullets[i].GetPosition().y << endl;
					 // cout << "Velocity: " << bullets[i].Get_Velocity().x << ", " <<  bullets[i].Get_Velocity().y << "\n\n";
	
            }//Check to see if bullet state is alive         		
       }//for loop   
	   */


	list< Particles >::iterator i = p_obj.begin();

	

	while( i != p_obj.end() )
	{
		if(i->Get_State() != PS_DEAD)
		{
		

			sf::Vector2f final_vel;
			final_vel.x = i->velocity.x;
	 		final_vel.y = i->velocity.y;

			//Standard particle behavior
			Particle_Factory::Standard_Logic(*i);

	
			/*
			//Scroll with Map
			if(( Cam.canScroll_Left() ) || ( Cam.canScroll_Right() ))
			{
				final_vel.x -= player.Get_Velocity().x; 
			}
			if((  Cam.canScroll_Down() ) || (  Cam.canScroll_Up() ))
			{
				final_vel.y -= player.Get_Velocity().y; 
			}
		
		*/
			//Move teh particle
			if(i->type == AT_SLUGS)
			{
				//final_vel.x =  ( sin(degreesToRadians(i->angle)) ) * 1000;
				//final_vel.x += cos(  degreesToRadians(i->angle ) ) * 20;
				//final_vel.y =  (cos(degreesToRadians(i->angle)) ) * 1000;
				//final_vel.y += sin( degreesToRadians(i->angle )) * 20;
			}

				

			



			//loop through to the next particle
			i++;

		}else{
			if(i->type == PT_SLUGS)
			{
				Emit("Slug_R2", i->GetPosition(), 0, 19);
			}
			//erase particle
			i = p_obj.erase(i);
			
		}
	}//end ov for
}//EoF



/**** Projectile Class Stuff ****/
/********************************/
/* Set/Get Bullet Speed */
void Projectile::Set_Speed(float min, float max)
{
	speed = sf::Randomizer::Random(min, max);
}
